package fr.norsys.mapper.console.service;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;

import org.apache.commons.beanutils.BeanUtils;

import fr.norsys.mapper.console.exception.ConnectionException;
import fr.norsys.mapper.console.exception.FileException;
import fr.norsys.mapper.console.model.Connection;
import fr.norsys.mapper.console.model.ConnectionNameComparator;
import fr.norsys.mapper.console.utils.UIDGenerator;

public class ConnectionServiceImpl implements ConnectionService {
	private String connectionsDirPath;
	private FileService fileService;
	private static String propFileExt = ".properties";
	public void save(Connection connection, Collection connections) throws ConnectionException {
		if(connection.getId() == null || "".equals(connection.getId()))
			{add(connection,connections);}
		else
			{modify(connection,connections);}
	}
	private void add(Connection connection, Collection connections) throws ConnectionException {
		Connection c = null;
		try {
			c = (Connection) BeanUtils.cloneBean(connection);
		} catch (Exception e) {
			throw new ConnectionException("Unable to clone bean "+c);
		}
		c.setId(UIDGenerator.generateId());
		connections.add(c);
		try {
			fileService.createNewFile(c.getName()+propFileExt,connectionsDirPath);
		} catch (FileException e) {
			throw new ConnectionException(e.toString());
		}
	}
	private void modify(Connection conn, Collection connections)  throws ConnectionException{
		Connection connection = conn;
		for (Iterator it = connections.iterator(); it.hasNext();) {
			Connection c = (Connection) it.next();
			if (connection.getId().equals(c.getId())) {
				if (!connection.getName().equals(c.getName())) {
					try {
						fileService.changeFileName(c.getName()+propFileExt, connection.getName()+propFileExt, connectionsDirPath);
					} catch (FileException e) {
						throw new ConnectionException(e.toString());
					}
				}
				fr.norsys.mapper.console.utils.BeanUtils.copyFilledProperties(
						c, connection);
				connection=c;
				return;
			}
		}
	}

	public void delete(String id, Collection connections)  throws ConnectionException{
		for (Iterator it = connections.iterator(); it.hasNext();) {
			Connection c = (Connection) it.next();
			if (c.getId().equals(id)) {
				connections.remove(c);
				try {
					fileService.deleteFile(c.getName()+".properties",connectionsDirPath);
				} catch (FileException e) {
					throw new ConnectionException(e.toString());
				}
				break;
			}
		}
	}

	public Connection get(String id, Collection connections) throws ConnectionException {
		Connection result = null;
		for (Iterator it = connections.iterator(); it.hasNext();) {
			Connection c = (Connection) it.next();
			if (c.getId().equals(id)) {
				result = c;
				break;
			}
		}
		return result;
	}
	public Collection getConnectionsFromFileSystem()  throws ConnectionException{
		List connectionsNames;
		try {
			connectionsNames = fileService.getFilesName(connectionsDirPath,propFileExt);
		} catch (FileException e) {
			throw new ConnectionException(e.toString());
		}
		Collection connections = new TreeSet(new ConnectionNameComparator());
		Connection c = null;
		for(Iterator i=connectionsNames.iterator();i.hasNext();){
			c = new Connection((String)i.next());
			connections.add(c);
		}
		return connections;
	}
	public FileService getFileService() {
		return fileService;
	}
	public void setFileService(FileService fileService) {
		this.fileService = fileService;
	}
	public String getConnectionsDirPath() {
		return connectionsDirPath;
	}
	public void setConnectionsDirPath(String connectionsDirPath) {
		this.connectionsDirPath = connectionsDirPath;
	}
}